package com.nuoniu.sibanyun.service.so.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.bo.*;
import com.nuoniu.sibanyun.entity.erp.ErpNumberSet;
import com.nuoniu.sibanyun.entity.inOut.VInOutRecordDetail;
import com.nuoniu.sibanyun.entity.inOut.VInOutRecordMain;
import com.nuoniu.sibanyun.entity.so.VSaleDeliveryDetail;
import com.nuoniu.sibanyun.entity.so.VSaleDeliveryMain;
import com.nuoniu.sibanyun.mapper.erp.ErpNumberSetMapper;
import com.nuoniu.sibanyun.mapper.so.VSaleDeliveryMainMapper;
import com.nuoniu.sibanyun.service.crm.ICrmGoodsService;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpNumberSetService;
import com.nuoniu.sibanyun.service.erp.IErpVoucherDesignService;
import com.nuoniu.sibanyun.service.erp.in.IInWarehouseService;
import com.nuoniu.sibanyun.service.msg.ISysMsgService;
import com.nuoniu.sibanyun.service.so.IVSaleDeliveryDetailService;
import com.nuoniu.sibanyun.service.so.IVSaleDeliveryMainService;
import com.nuoniu.sibanyun.service.utils.ErpUtils;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;

/**
 * <p>
 * 销售发货单主表 服务实现类
 * </p>
 *
 * @author 小啊刚
 * @since 2020-12-07
 */
@Service
public class VSaleDeliveryMainServiceImpl extends ServiceImpl<VSaleDeliveryMainMapper, VSaleDeliveryMain> implements IVSaleDeliveryMainService {

    @Autowired
    private IVSaleDeliveryDetailService saleDeliveryDetailService;
    @Autowired
    private IErpAccountService erpAccountService;
    @Autowired
    private ErpNumberSetMapper numberSetMapper;
    @Autowired
    private IErpNumberSetService numberSetService;
    @Autowired
    private IErpVoucherDesignService erpVoucherDesignService;
    @Autowired
    private IInWarehouseService iInWarehouseService;
    @Autowired
    private ICrmGoodsService crmGoodsService;
    @Autowired
    private ISysMsgService msgService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveDelivery(VSaleDeliveryMain saleDeliveryMain) {

        Boolean isNewMain = false;
        Long mainId = saleDeliveryMain.getId();
        List<VSaleDeliveryDetail> orderDetailList = saleDeliveryMain.getOrderDetailList();
        if(null == orderDetailList) {
            throw new NuoNiuException("单据明细不能为空");
        }
        UserInfo userInfo = UserThreadLocal.get();
        Integer accountId = erpAccountService.getCurrentAccountId();
        VSaleDeliveryMain oldVSaleDeliveryMain = null;
        Integer businessType = saleDeliveryMain.getBusinessType();
//        if( null != businessType && (96 == businessType || 98 == businessType) && orderDetailList.stream().anyMatch(f->f.getBaseQuantity().compareTo(BigDecimal.ZERO) > 0)){
//            throw new NuoNiuException("单据明细错误：退货业务的明细数量不能为正数");
//        }
        if(mainId == null) {
            isNewMain = true;
            String code = getCode();
            if(StringUtils.isBlank(code)) {
                throw new NuoNiuException("单据编码今日已上限");
            }
            //校验详情（详情不能有ID）
            boolean isHaveId = orderDetailList.stream().anyMatch(f -> null != f.getId());
            if(isHaveId) {
                throw new NuoNiuException("单据明细错误：不能新增已经存在的明细记录");
            }
            saleDeliveryMain.setVoucherState(-1);
            saleDeliveryMain.setVoucherCode(code);
            saleDeliveryMain.setAccountId(accountId);
            saleDeliveryMain.setCompanyId(userInfo.getCompanyId());
            saleDeliveryMain.setCreateUserId(userInfo.getUserId());
            saleDeliveryMain.setCreateUserName(userInfo.getRealName());
            if (null == saleDeliveryMain.getBusinessType()){
                saleDeliveryMain.setBusinessType(0);
            }
        }else {
            //校验详情（详情不能有其他单据的明细ID）
            boolean isHaveErrorId = orderDetailList.stream().anyMatch(f -> null != f.getOrderId() && !mainId.toString().equals(f.getOrderId().toString()));
            if(isHaveErrorId) {
                throw new NuoNiuException("单据明细错误：不能修改其他单据的明细记录");
            }
            saleDeliveryMain.setUpdateDate(LocalDateTime.now());
            saleDeliveryMain.setUpdateUserId(userInfo.getUserId());
            saleDeliveryMain.setCreateUserName(userInfo.getRealName());
            oldVSaleDeliveryMain = getById(mainId);
            /**************  修改权限 *******************/
            if(!crmGoodsService.isHaveOperationRight(oldVSaleDeliveryMain.getCreateUserId().longValue())){
                throw new NuoNiuException("你没有权限操作该记录");
            }
            Integer voucherState = oldVSaleDeliveryMain.getVoucherState();
            if(null != voucherState && voucherState > 0){
                throw new NuoNiuException("已审核,不能修改");
            }
            saleDeliveryMain.setAccountId(oldVSaleDeliveryMain.getAccountId());
            saleDeliveryMain.setSourceVoucherCode(oldVSaleDeliveryMain.getSourceVoucherCode());
            saleDeliveryMain.setSourceVoucherId(oldVSaleDeliveryMain.getSourceVoucherId());
            saleDeliveryMain.setSourceVoucherType(oldVSaleDeliveryMain.getSourceVoucherType());
            saleDeliveryMain.setSourceVoucherDate(oldVSaleDeliveryMain.getSourceVoucherDate());

            if (null != saleDeliveryMain.getBusinessType() && 96 == saleDeliveryMain.getBusinessType() &&  2 == oldVSaleDeliveryMain.getVoucherState()){
                throw new NuoNiuException("销售发货单,已经提交申请发货，不能冲抵");
            }
            //不可更新字段
            saleDeliveryMain.setVoucherCode(null);
        }
        saleDeliveryMain.setCumExecuteQuantity(null);
        saleDeliveryMain.setCumRetQuantity(null);
        // 校验 明细数量
//        if( null != saleDeliveryMain.getBusinessType() && (98 == saleDeliveryMain.getBusinessType() || 96 == saleDeliveryMain.getBusinessType())){
//            boolean isOk = saleDeliveryMain.getOrderDetailList().stream().anyMatch(f -> null == f.getBaseQuantity() || !(f.getBaseQuantity().compareTo(BigDecimal.ZERO) < 0));
//            if(isOk)throw new NuoNiuException("明细数量必须小于0");
//        }else{
//            boolean isOk = saleDeliveryMain.getOrderDetailList().stream().anyMatch(f -> null == f.getBaseQuantity() || !(f.getBaseQuantity().compareTo(BigDecimal.ZERO) > 0));
//            if(isOk)throw new NuoNiuException("明细数量必须大于0");
//        }
        boolean isOk = saleDeliveryMain.getOrderDetailList().stream().anyMatch(f -> null == f.getBaseQuantity() || !(f.getBaseQuantity().compareTo(BigDecimal.ZERO) > 0));
        if(isOk) {
            throw new NuoNiuException("明细数量必须大于0");
        }
        //计算 明细物料 总数
        BigDecimal totalQuantity =  saleDeliveryMain.getOrderDetailList().stream().map(VSaleDeliveryDetail::getBaseQuantity).reduce(BigDecimal.ZERO,BigDecimal::add);
        saleDeliveryMain.setTotalQuantity(totalQuantity.abs());

        Boolean result = this.saveOrUpdate(saleDeliveryMain);
        if(result) {
            List<Long> detailIds = new ArrayList<>();
            orderDetailList.forEach(p -> {
                p.setOrderId(saleDeliveryMain.getId().intValue());
                p.setCompanyId(userInfo.getCompanyId());
                p.setAccountId(saleDeliveryMain.getAccountId());
                p.setSourceVoucherCode(saleDeliveryMain.getSourceVoucherCode());
                p.setSourceVoucherType(saleDeliveryMain.getSourceVoucherType());
                p.setSourceVoucherId(saleDeliveryMain.getSourceVoucherId());
                p.setSourceVoucherDate(saleDeliveryMain.getSourceVoucherDate());
                if(p.getId() != null) {
                    detailIds.add(p.getId());
                }
            });

            boolean isDealDelete = false;
            if (null != mainId){
                //删除明细
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("order_id", mainId);
                if(detailIds != null && detailIds.size() > 0) {
                    wrapper.notIn("id", detailIds);
                }
                isDealDelete = saleDeliveryDetailService.remove(wrapper);
            }
            //保存单据明细表
            saleDeliveryDetailService.saveOrUpdateBatch(orderDetailList);
            // *** 如果 来源订单不为空,校验
            if(null != saleDeliveryMain.getSourceVoucherId()){
                if(isDealDelete) {
                    throw new NuoNiuException("有来源的单据不能删除明细");
                }
                if( !"SaleOrder".equals(saleDeliveryMain.getSourceVoucherType()) && !"SaleDelivery".equals(saleDeliveryMain.getSourceVoucherType())) {
                    throw new NuoNiuException("销售发货单的来源单，只能是销售发货单或者销售订单");
                }
                if( null != saleDeliveryMain.getBusinessType() && (98 == saleDeliveryMain.getBusinessType() || 96 == saleDeliveryMain.getBusinessType()) && !"SaleDelivery".equals(saleDeliveryMain.getSourceVoucherType())) {
                    throw new NuoNiuException("退货流程的销售发货单的来源单，只能是销售发货单");
                }
                if( null != saleDeliveryMain.getBusinessType() && (98 != saleDeliveryMain.getBusinessType() &&  96 != saleDeliveryMain.getBusinessType()) && !"SaleOrder".equals(saleDeliveryMain.getSourceVoucherType())) {
                    throw new NuoNiuException("非退货流程的销售发货单的来源单，只能是销售订单");
                }
                VoucherSearchBo voucherSearchBo = new VoucherSearchBo();
                voucherSearchBo.setSourceVoucherId(saleDeliveryMain.getSourceVoucherId());
                voucherSearchBo.setSourceVoucherType(saleDeliveryMain.getSourceVoucherType());
                voucherSearchBo.setVoucherId(saleDeliveryMain.getId().intValue());
                voucherSearchBo.setVoucherType("SaleDelivery");
                if( null != saleDeliveryMain.getBusinessType() && 98 == saleDeliveryMain.getBusinessType()){
                    VoucherMainRetBo voucherMainRetBo = new VoucherMainRetBo();
                    BeanUtils.copyProperties(saleDeliveryMain,voucherMainRetBo);
                    List<VoucherDetailRetBo> voucherDetailRetBos = new ArrayList<>();
                    orderDetailList.forEach(detail->{
                        VoucherDetailRetBo voucherDetailRetBo = new VoucherDetailRetBo();
                        voucherDetailRetBos.add(voucherDetailRetBo);
                        BeanUtils.copyProperties(detail,voucherDetailRetBo);
                    });
                    //如果 是从 “退货冲抵” 到 “普通退货”，则先删除 冲抵执行情况，再做普通退货业务
                    if(null != oldVSaleDeliveryMain  &&  null != oldVSaleDeliveryMain.getBusinessType() && oldVSaleDeliveryMain.getBusinessType() == 96){
                        VoucherMainBo voucherMainBo = new VoucherMainBo();
                        BeanUtils.copyProperties(saleDeliveryMain,voucherMainBo);
                        voucherMainBo.setBusinessType(96);
                        List<VoucherDetailBo> voucherDetailBos = new ArrayList<>();
                        orderDetailList.forEach(detail->{
                            VoucherDetailBo voucherDetailBo = new VoucherDetailBo();
                            voucherDetailBos.add(voucherDetailBo);
                            BeanUtils.copyProperties(detail,voucherDetailBo);
                        });
                        voucherSearchBo.setCalculateType(2);
                        erpVoucherDesignService.calculateSourceVoucher(voucherMainBo,voucherDetailBos,voucherSearchBo);
                    }
                    voucherSearchBo.setCalculateType(1);
                    erpVoucherDesignService.calculateRetQuantity(voucherMainRetBo,voucherDetailRetBos,voucherSearchBo);
                }else{
                    VoucherMainBo voucherMainBo = new VoucherMainBo();
                    BeanUtils.copyProperties(saleDeliveryMain,voucherMainBo);
                    voucherMainBo.setIsNewMain(isNewMain);
                    List<VoucherDetailBo> voucherDetailBos = new ArrayList<>();
                    orderDetailList.forEach(detail->{
                        VoucherDetailBo voucherDetailBo = new VoucherDetailBo();
                        voucherDetailBos.add(voucherDetailBo);
                        BeanUtils.copyProperties(detail,voucherDetailBo);
                    });
                    //如果 是从 “普通退货” 到 “退货冲抵”，则先删除 普通退货 执行情况，再做普通退货业务
                    if(null != saleDeliveryMain.getBusinessType() && 96 == saleDeliveryMain.getBusinessType() && null != oldVSaleDeliveryMain && null != oldVSaleDeliveryMain.getBusinessType() &&  oldVSaleDeliveryMain.getBusinessType() == 98){
                        VoucherMainRetBo voucherMainRetBo = new VoucherMainRetBo();
                        voucherMainBo.setBusinessType(98);
                        BeanUtils.copyProperties(saleDeliveryMain,voucherMainRetBo);
                        List<VoucherDetailRetBo> voucherDetailRetBos = new ArrayList<>();
                        orderDetailList.forEach(detail->{
                            VoucherDetailRetBo voucherDetailRetBo = new VoucherDetailRetBo();
                            voucherDetailRetBos.add(voucherDetailRetBo);
                            BeanUtils.copyProperties(detail,voucherDetailRetBo);
                        });
                        voucherSearchBo.setCalculateType(2);
                        erpVoucherDesignService.calculateRetQuantity(voucherMainRetBo,voucherDetailRetBos,voucherSearchBo);
                    }
                    voucherSearchBo.setCalculateType(1);
                    erpVoucherDesignService.calculateSourceVoucher(voucherMainBo,voucherDetailBos,voucherSearchBo);
                }

            }
        }
    }

    @Override
    public Set<Long> saveOrderForWarehouse(VSaleDeliveryMain saleDeliveryMain) {
        Set<Long> idSet = new HashSet<>();
        Map<Integer,List<VSaleDeliveryDetail>> warehouseIdMap = new HashMap<>();
        List<VSaleDeliveryDetail> orderDetailList = saleDeliveryMain.getOrderDetailList();
        orderDetailList.forEach(detail->{
            Integer warehouseId = detail.getWarehouseId();
            VSaleDeliveryDetail newDetail = new VSaleDeliveryDetail();
            BeanUtils.copyProperties(detail,newDetail);
            List<VSaleDeliveryDetail> newDetailList = warehouseIdMap.get(warehouseId);
            if(null == newDetailList){
                newDetailList = new ArrayList<>();
                warehouseIdMap.put(warehouseId,newDetailList);
            }
            newDetailList.add(newDetail);
        });

        for (Integer warehouseId : warehouseIdMap.keySet()) {
            VSaleDeliveryMain newMain = new VSaleDeliveryMain();
            BeanUtils.copyProperties(saleDeliveryMain,newMain);
            List<VSaleDeliveryDetail> vInOutRecordDetails = warehouseIdMap.get(warehouseId);
            BigDecimal totalQuantity = vInOutRecordDetails.stream().map(VSaleDeliveryDetail::getBaseQuantity).reduce(BigDecimal.ZERO,BigDecimal::add);
            newMain.setTotalQuantity(totalQuantity.abs());
            VSaleDeliveryDetail vSaleDeliveryDetail = vInOutRecordDetails.get(0);
            String warehouseName = vSaleDeliveryDetail.getWarehouseName();
            String warehouseCode = vSaleDeliveryDetail.getWarehouseCode();
            newMain.setWarehouseId(warehouseId);
            newMain.setWarehouseName(warehouseName);
            newMain.setWarehouseCode(warehouseCode);
            newMain.setOrderDetailList(vInOutRecordDetails);
            saveDelivery(newMain);
            idSet.add(newMain.getId());
        }
        return idSet;
    }

    @Override
    public void submit(Long id, Integer status) {
        if(null == id || null == status || (null != status && (status > 0 || status < -1 ))) {
            throw new NuoNiuException("参数错误");
        }
        UserInfo userInfo = UserThreadLocal.get();
        VSaleDeliveryMain saleDeliveryMain = this.getById(id);
        if( null == saleDeliveryMain) {
            throw new NuoNiuException("记录不存在");
        }
        //校验状态
        Integer voucherState = saleDeliveryMain.getVoucherState();
        /**  统一校验 提交状态 */
        ErpUtils.checkSubmitStatus(voucherState,status);
        //提交
        saleDeliveryMain.setVoucherState(status);
        saleDeliveryMain.setSubmitDate(LocalDateTime.now());
        saleDeliveryMain.setSubmitUserId(userInfo.getUserId());
        saleDeliveryMain.setSubmitUserName(userInfo.getRealName());
        this.updateById(saleDeliveryMain);

        if(status.equals(0)) {
            msgService.saleDeliveryNotice(saleDeliveryMain);
        }
    }

    @Override
    public void examine(Long id, Integer status) {
        if(null == id || null == status ||  (status > 1 || status < 0) ) {
            throw new NuoNiuException("参数错误");
        }
        UserInfo userInfo = UserThreadLocal.get();
        VSaleDeliveryMain saleDeliveryMain = getById(id);

        if (null == saleDeliveryMain) {
            throw new NuoNiuException("参数错误");
        }
        Integer voucherState = saleDeliveryMain.getVoucherState();
        BigDecimal cumExecuteQuantity = saleDeliveryMain.getCumExecuteQuantity();
        /** 统一校验 审核状态*/
        ErpUtils.checkExamineStatus(voucherState,status,cumExecuteQuantity);
        saleDeliveryMain.setVoucherState(status);
        saleDeliveryMain.setReviewerUserId(userInfo.getUserId());
        saleDeliveryMain.setReviewerUserName(userInfo.getRealName());
        saleDeliveryMain.setReviewerDate(LocalDateTime.now());
        updateById(saleDeliveryMain);

//        if(status.equals(1)) {
//            msgService.saleDeliveryNotice(saleDeliveryMain);
//        }
    }

    @Override
    public void apply(Long id, Integer status) {
        if (!(1 == status || 2 == status)) {
            throw new NuoNiuException("参数错误");
        }
        UserInfo userInfo = UserThreadLocal.get();
        VSaleDeliveryMain saleDeliveryMain = getById(id);
        if (null == saleDeliveryMain) {
            throw new NuoNiuException("参数错误");
        }
        Integer businessType = saleDeliveryMain.getBusinessType();
        if (null != businessType && 96 == businessType) {
            throw new NuoNiuException("冲抵业务，不能做退单操作");
        }
        BigDecimal cumExecuteQuantity = saleDeliveryMain.getCumExecuteQuantity();
        if(null != cumExecuteQuantity && cumExecuteQuantity.compareTo(BigDecimal.ZERO) > 0) {
            throw new NuoNiuException("已经生单，不能做退单操作");
        }
        Integer voucherState = saleDeliveryMain.getVoucherState();
        if(  voucherState > 2 ) {
            throw new NuoNiuException("已经关闭，不能做申请/退单操作");
        }
        if (1 == status){
            if( 1  == voucherState ) {
                throw new NuoNiuException("未提交，不能做退单操作");
            }
            /****************  仓库权限校验 ——开始   ********************/
            Integer warehouseId = saleDeliveryMain.getWarehouseId();
            boolean isHaveOperationRight = iInWarehouseService.isHaveOperationRight(warehouseId.longValue());
            if(!isHaveOperationRight) {
                throw new NuoNiuException("你没有该仓库的没有操作权限");
            }
            /****************  仓库权限校验 ——结束   ********************/
        }
        if( 2  == voucherState && 2 == status) {
            throw new NuoNiuException("未审核，不能做申请操作");
        }
        saleDeliveryMain.setVoucherState(status);
        saleDeliveryMain.setReviewerUserId(userInfo.getUserId());
        saleDeliveryMain.setReviewerUserName(userInfo.getRealName());
        saleDeliveryMain.setReviewerDate(LocalDateTime.now());
        updateById(saleDeliveryMain);
    }

    @Override
    public boolean checkDataSourceFromInOut(VInOutRecordMain vInOutRecordMain) {
        String dataSource = vInOutRecordMain.getDataSource();
        String sourceVoucherType = vInOutRecordMain.getSourceVoucherType();
        Integer sourceVoucherId = vInOutRecordMain.getSourceVoucherId();
        List<VInOutRecordDetail> inOutDetailList = vInOutRecordMain.getOrderDetailList();
        if (!("SaleDispatchVoucher".equals(dataSource) && "SaleDelivery".equals(sourceVoucherType))) {
            throw new NuoNiuException("校验失败，数据来源错误");
        }
        VSaleDeliveryMain saleDeliveryMain = getById(sourceVoucherId);
        List<VSaleDeliveryDetail> vSaleDeliveryDetailList = saleDeliveryDetailService.getSimpleDetailsByOrderId(saleDeliveryMain.getId());
        Map<Long,VInOutRecordDetail> inOutDetailMap = new HashMap<>();
        inOutDetailList.forEach(detail->inOutDetailMap.put(detail.getSourceDetailId().longValue(),detail));
        vSaleDeliveryDetailList.forEach(vSaleDeliveryDetail->{
            Long detailId = vSaleDeliveryDetail.getId();
            VInOutRecordDetail inOutDetail = inOutDetailMap.get(detailId.longValue());
            if (null == inOutDetail) {
                throw new NuoNiuException("校验失败，来源明细数据不完整，缺失明细物料：" + vSaleDeliveryDetail.getInventoryName());
            }
            if (!(null != inOutDetail.getInventoryId() && null != vSaleDeliveryDetail.getInventoryId())) {
                throw new NuoNiuException("校验失败,明细物料数据错误");
            }
            if (!inOutDetail.getInventoryId().equals(vSaleDeliveryDetail.getInventoryId())) {
                throw new NuoNiuException("明细物料不一致，发货单明细物料名称：" + vSaleDeliveryDetail.getInventoryName() +",出库单明细物料名称：" + inOutDetail.getInventoryName());
            }
            if (!(null != inOutDetail.getBaseQuantity() && null != vSaleDeliveryDetail.getBaseQuantity())) {
                throw new NuoNiuException("校验失败,明细物料数据数量不可为空");
            }
            if (inOutDetail.getBaseQuantity().compareTo(vSaleDeliveryDetail.getBaseQuantity()) != 0) {
                throw new NuoNiuException("明细物料数量不一致，发货单明细物料名称：" + vSaleDeliveryDetail.getInventoryName() +"("+vSaleDeliveryDetail.getBaseQuantity()+"),出库单明细物料名称：" + inOutDetail.getInventoryName() +"("+inOutDetail.getBaseQuantity()+")");
            }

        });
        return true;
    }

    @Override
    public String getCode() {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        ErpNumberSet numberSet = numberSetMapper.getByCode("SaleDelivery", userInfo.getCompanyId(), currentAccountId);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getCode(userInfo.getCompanyId(), dateStr);
        return numberSetService.getCode(numberSet, code);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteById(Long id) {
        UserInfo userInfo = UserThreadLocal.get();
        VSaleDeliveryMain saleDeliveryMain = this.getById(id);
        if(saleDeliveryMain == null) {
            throw new NuoNiuException("删除失败，记录不存在");
        }
        /**************  修改权限 *******************/
        if(!crmGoodsService.isHaveOperationRight(saleDeliveryMain.getCreateUserId().longValue())){
            throw new NuoNiuException("你没有权限操作该记录");
        }
        BigDecimal cumExecuteQuantity = saleDeliveryMain.getCumExecuteQuantity();
        BigDecimal cumRetQuantity = saleDeliveryMain.getCumRetQuantity();
        if((null != cumExecuteQuantity && cumExecuteQuantity.compareTo(BigDecimal.ZERO) > 0) || (null != cumRetQuantity && cumRetQuantity.compareTo(BigDecimal.ZERO) > 0)){
            throw new NuoNiuException("销售发货单据已生成销售退货单据或者销售出库单据，不能删除");
        }
        //查询 明细
        List<VSaleDeliveryDetail> orderDetails = saleDeliveryDetailService.getDetailsByOrderId(id);
        // *** 如果 来源订单不为空
        if(null != saleDeliveryMain.getSourceVoucherId()){
            VoucherSearchBo voucherSearchBo = new VoucherSearchBo();
            voucherSearchBo.setCalculateType(2);
            voucherSearchBo.setSourceVoucherId(saleDeliveryMain.getSourceVoucherId());
            voucherSearchBo.setSourceVoucherType(saleDeliveryMain.getSourceVoucherType());
            voucherSearchBo.setVoucherId(saleDeliveryMain.getId().intValue());
            voucherSearchBo.setVoucherType("SaleDelivery");
            if(null != saleDeliveryMain.getBusinessType() && 98 == saleDeliveryMain.getBusinessType()){
                VoucherMainRetBo voucherMainRetBo = new VoucherMainRetBo();
                BeanUtils.copyProperties(saleDeliveryMain,voucherMainRetBo);
                List<VoucherDetailRetBo> voucherDetailRetBos = new ArrayList<>();
                orderDetails.forEach(detail->{
                    VoucherDetailRetBo voucherDetailRetBo = new VoucherDetailRetBo();
                    voucherDetailRetBos.add(voucherDetailRetBo);
                    BeanUtils.copyProperties(detail,voucherDetailRetBo);
                });
                erpVoucherDesignService.calculateRetQuantity(voucherMainRetBo,voucherDetailRetBos,voucherSearchBo);
            }else{
                VoucherMainBo voucherMainBo = new VoucherMainBo();
                BeanUtils.copyProperties(saleDeliveryMain,voucherMainBo);
                List<VoucherDetailBo> voucherDetailBos = new ArrayList<>();
                orderDetails.forEach(detail->{
                    VoucherDetailBo voucherDetailBo = new VoucherDetailBo();
                    voucherDetailBos.add(voucherDetailBo);
                    BeanUtils.copyProperties(detail,voucherDetailBo);
                });
                erpVoucherDesignService.calculateSourceVoucher(voucherMainBo,voucherDetailBos,voucherSearchBo);
            }

        }
        removeById(id);
    }


}
